﻿#include "LoadManager.h"

typedef SER_INSTANCE (*DllFun)(SerLoad *ser);
typedef UI_INSTANCE (*DllUiFun)(QWidget *parent,ViewLoad *view);

//在类外对类内静态变量初始化
QString toolPath = QProcessEnvironment::systemEnvironment().value("ComponentTool");//获取系统环境变量
QDir ILoadManager::sLibDir=QDir(toolPath.append("/DLLLibrary/"));//设置dll文件所在路径
/*****************************************ILoadManager******************************************/
ILoadManager::ILoadManager(const QString& dllName,Logger* logger):mComName(dllName),logger(logger)
{
	this->mLib.setFileName(sLibDir.absoluteFilePath(dllName));
	this->logger&&this->logger->d(mComName,QStringLiteral("载入组件文件\t")+mLib.fileName()+".dll");
	bool isLoaded = mLib.isLoaded()||this->mLib.load();
	this->logger&&this->logger->i(mComName,isLoaded?QStringLiteral("dll文件载入成功"):QStringLiteral("dll文件载入失败"));
	Q_ASSERT(isLoaded);
}
void ILoadManager::setLogger(Logger* logger)
{
	this->logger=logger;
}
const QString ILoadManager::QueryState(const QString& instanceName)
{
	return mStateMap.value(instanceName,QString("UnLoaded"));
}
const QString& ILoadManager::GetComponentName()
{
	return mComName;
}
ILoadManager::~ILoadManager(void)
{
	bool isOK = this->mLib.isLoaded()&&this->mLib.unload();
	this->logger&&this->logger->i(mComName,isOK?QStringLiteral("dll文件卸载成功"):QStringLiteral("dll文件卸载失败"));
}
/*****************************************SerLoadManager******************************************/
void SerLoadManager::Load(SerLoad* ptrSerLoad)//这是子类特有的方法
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("Loading..."));
	auto pFunc = reinterpret_cast<DllFun>(mLib.resolve("CreateComponent"));
	if (pFunc!=nullptr)
	{
		ptrSerLoad->pBaseSer = pFunc(ptrSerLoad);
		QString instanceName=QString::fromStdString(ptrSerLoad->instanceName);
		mSerLoadMap.insert(instanceName,ptrSerLoad);
		mStateMap[instanceName]=QStringLiteral("Loaded");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("Loaded"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("Load失败,找不到CreateComponent函数"));
		Q_ASSERT_X(pFunc!=nullptr,__FILE__,"can not find the func named 'CreateComponent' in the dll file");
	}
}
void SerLoadManager::Load(void* pSerLoad)//这是子类重写父类的虚方法，不能在子类重写父类的虚方法中调用子类特有的方法
{
	auto ptrSerLoad=static_cast<SerLoad*> (pSerLoad);
	QString instanceName=QString::fromStdString(ptrSerLoad->instanceName);
	if (!mSerLoadMap.contains(instanceName))
	{
		this->logger&&this->logger->d(this->mComName,QStringLiteral("Loading..."));
		auto pFunc = reinterpret_cast<DllFun>(mLib.resolve("CreateComponent"));
		if (pFunc!=nullptr)
		{
			ptrSerLoad->pBaseSer = pFunc(ptrSerLoad);
			mSerLoadMap.insert(instanceName,ptrSerLoad);
			mStateMap[instanceName]=QStringLiteral("Loaded");
			this->logger&&this->logger->i(this->mComName,QStringLiteral("Loaded"));
		}
		else
		{
			this->logger&&this->logger->e(this->mComName,QStringLiteral("Load失败,找不到CreateComponent函数"));
			Q_ASSERT_X(pFunc!=nullptr,__FILE__,"can not find the func named 'CreateComponent' in the dll file");
		}
	}
}
void SerLoadManager::Init(const QString& instanceName)
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("Initializing..."));
	auto pSerLoad = mSerLoadMap.value(instanceName,nullptr);
	if (pSerLoad!=nullptr&&pSerLoad->pBaseSer!=nullptr)
	{
		pSerLoad->pBaseSer->InitComponent();
		mStateMap[instanceName]=QStringLiteral("Initialized");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("Initialized"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("Initialize失败"));
	}
}
void SerLoadManager::Active(const QString& instanceName)
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("Activating..."));
	auto pSerLoad = mSerLoadMap.value(instanceName,nullptr);
	if (pSerLoad!=nullptr&&pSerLoad->pBaseSer!=nullptr)
	{
		pSerLoad->pBaseSer->ActivateComponent();
		mStateMap[instanceName]=QStringLiteral("Activated");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("Activated"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("Active失败"));
	}
}
void SerLoadManager::UnActive(const QString& instanceName)
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("UnActivating..."));
	auto pSerLoad = mSerLoadMap.value(instanceName,nullptr);
	if (pSerLoad!=nullptr&&pSerLoad->pBaseSer!=nullptr)
	{
		pSerLoad->pBaseSer->UnActivateComponent();
		mStateMap[instanceName]=QStringLiteral("UnActivated");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("UnActivated"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("UnActive失败"));
	}
}
void SerLoadManager::UnLoad(const QString& instanceName)
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("UnLoading..."));
	auto pSerLoad = mSerLoadMap.value(instanceName,nullptr);
	if (pSerLoad!=nullptr&&pSerLoad->pBaseSer!=nullptr)
	{
		pSerLoad->pBaseSer->FreeComponent();
		//delete pSerLoad->pBaseSer;
		//pSerLoad->pBaseSer=nullptr;
		mStateMap[instanceName]=QStringLiteral("UnLoaded");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("UnLoaded"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("UnLoad失败"));
	}
}
/*****************************************ViewLoadManager******************************************/
void ViewLoadManager::Load(ViewLoad* ptrViewLoad)
{	
	this->logger&&this->logger->d(this->mComName,QStringLiteral("Loading..."));
	auto pFunc = reinterpret_cast<DllUiFun>(mLib.resolve("CreatePlugin"));
	if (pFunc!=nullptr)
	{
		ptrViewLoad->pBaseUi = pFunc(mParent,ptrViewLoad);
		QString instanceName=QString::fromStdString(ptrViewLoad->instanceName);
		mViewLoadMap.insert(instanceName,ptrViewLoad);
		ILoadManager::mStateMap[instanceName]=QStringLiteral("Loaded");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("Loaded"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("Load失败,找不到CreatePlugin函数"));
		Q_ASSERT_X(pFunc!=nullptr,__FILE__,"can not find the func named 'CreatePlugin' in the dll file");
	}
}
void ViewLoadManager::Load(void* pViewLoad)
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("Loading..."));
	auto ptrViewLoad=static_cast<ViewLoad*>(pViewLoad);
	auto pFunc = reinterpret_cast<DllUiFun>(mLib.resolve("CreatePlugin"));
	if (pFunc!=nullptr)
	{
		ptrViewLoad->pBaseUi = pFunc(mParent,ptrViewLoad);
		QString instanceName=QString::fromStdString(ptrViewLoad->instanceName);
		mViewLoadMap.insert(instanceName,ptrViewLoad);
		ILoadManager::mStateMap[instanceName]=QStringLiteral("Loaded");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("Loaded"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("Load失败,找不到CreatePlugin函数"));
		Q_ASSERT_X(pFunc!=nullptr,__FILE__,"can not find the func named 'CreatePlugin' in the dll file");
	}
}
void ViewLoadManager::Init(const QString& instanceName)
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("Initializing..."));
	auto pViewLoad = mViewLoadMap.value(instanceName,nullptr);
	if (pViewLoad!=nullptr&&pViewLoad->pBaseUi!=nullptr)
	{
		pViewLoad->pBaseUi->InitPlugin();
		mStateMap[instanceName]=QStringLiteral("Initialized");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("Initialized"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("Initialize失败"));
	}
}
void ViewLoadManager::Active(const QString& instanceName)
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("Activating..."));
	auto pViewLoad = mViewLoadMap.value(instanceName,nullptr);
	if (pViewLoad!=nullptr&&pViewLoad->pBaseUi!=nullptr)
	{
		pViewLoad->pBaseUi->ActivatePlugin();
		pViewLoad->pBaseUi->ShowPlugin();
		mStateMap[instanceName]=QStringLiteral("Activated");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("Activated"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("Active失败"));
	}
}
void ViewLoadManager::UnActive(const QString& instanceName)
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("UnActivating..."));
	auto pViewLoad = mViewLoadMap.value(instanceName,nullptr);
	if (pViewLoad!=nullptr&&pViewLoad->pBaseUi!=nullptr)
	{
		pViewLoad->pBaseUi->UnActivatePlugin();
		pViewLoad->pBaseUi->HidePlugin();
		mStateMap[instanceName]=QStringLiteral("UnActivated");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("UnActivated"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("UnActive失败"));
	}
}
void ViewLoadManager::UnLoad(const QString& instanceName)
{
	this->logger&&this->logger->d(this->mComName,QStringLiteral("UnLoading..."));
	auto pViewLoad = mViewLoadMap.value(instanceName,nullptr);
	if (pViewLoad!=nullptr&&pViewLoad->pBaseUi!=nullptr)
	{
		pViewLoad->pBaseUi->FreePlugin();
		//delete pViewLoad->pBaseUi;
		//pViewLoad->pBaseUi=nullptr;
		mStateMap[instanceName]=QStringLiteral("UnLoaded");
		this->logger&&this->logger->i(this->mComName,QStringLiteral("UnLoaded"));
	}
	else
	{
		this->logger&&this->logger->e(this->mComName,QStringLiteral("UnLoad失败"));
	}
}
/*****************************************Logger******************************************/
Logger::Logger(const QString& logPath)
{
	logFile.setFileName(logPath);
	bool isOK = logFile.open(QIODevice::Append);
	Q_ASSERT(isOK);
}
Logger::~Logger()
{
	if (logFile.isOpen())
	{
		logFile.close();
	}
}
bool Logger::appendLog(const QString& componentName,const QString& msg,char level/* ='D' */)
{
	if (this->logFile.isOpen())
	{
		this->logFile.write("[");
		this->logFile.write(&level);
		this->logFile.write("]");
		this->logFile.write(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss:zzz").toLocal8Bit());
		this->logFile.write("\t[");
		this->logFile.write(componentName.toLocal8Bit());
		this->logFile.write("]\t");
		this->logFile.write(msg.toLocal8Bit());
		this->logFile.write("\n");
		return this->logFile.flush();
	}
	return false;
}
bool Logger::d(const QString& componentName,const QString& msg)
{
	return this->appendLog(componentName,msg,'D');
}
bool Logger::i(const QString& componentName,const QString& msg)
{
	return this->appendLog(componentName,msg,'I');
}
bool Logger::e(const QString& componentName,const QString& msg)
{
	return this->appendLog(componentName,msg,'E');
}
bool Logger::w(const QString& componentName,const QString& msg)
{
	return this->appendLog(componentName,msg,'W');
}
bool Logger::v(const QString& componentName,const QString& msg)
{
	return this->appendLog(componentName,msg,'V');
}